package com.gmlive.common.appupdate.download

import com.gmlive.common.appupdate._XUpdate
import com.gmlive.common.appupdate.logs.UpdateLog
import com.gmlive.common.appupdate.proxy.IUpdateHttpService
import com.liulishuo.okdownload.DownloadTask
import com.liulishuo.okdownload.core.cause.EndCause
import com.liulishuo.okdownload.core.cause.ResumeFailedCause
import com.liulishuo.okdownload.core.listener.DownloadListener1
import com.liulishuo.okdownload.core.listener.assist.Listener1Assist
import java.lang.Exception

class DefaultUpdateService(private val detector: IUpdateDetector): IUpdateHttpService {
    private var task: DownloadTask? = null

    // ------------- get 请求更新信息 ----------------
    override fun asyncGet(url: String, params: MutableMap<String, Any>, callBack: IUpdateHttpService.Callback) {
        detector.detectNewVersion(true, url, params, callBack)
    }

    // ------------- post 请求更新信息 ---------------
    override fun asyncPost(url: String, params: MutableMap<String, Any>, callBack: IUpdateHttpService.Callback) {
        detector.detectNewVersion(false, url, params, callBack)
    }

    // ------------- 下载 ------------
    override fun download(url: String, path: String, fileName: String, callback: IUpdateHttpService.DownloadCallback) {
        task = DownloadTask.Builder(url, path, fileName)
                .setWifiRequired(_XUpdate.isWifiOnly())
                .setAutoCallbackToUIThread(true)
                .setPassIfAlreadyCompleted(true)
                .setConnectionCount(5)
                .setMinIntervalMillisCallbackProcess(50)
                .build()

        task?.enqueue(DownloadListener(callback))
    }

    override fun cancelDownload(url: String) {
        if (url == task?.url){
            task?.cancel()
        }
    }

    /**
     * 新版本探测器
     */
    interface IUpdateDetector {
        /**
         * 从服务端获取新版本信息
         */
        fun detectNewVersion(isGet: Boolean, url: String, params: MutableMap<String, Any>, callBack: IUpdateHttpService.Callback)
    }

    private class DownloadListener(private val callback: IUpdateHttpService.DownloadCallback): DownloadListener1() {
        override fun taskStart(task: DownloadTask, model: Listener1Assist.Listener1Model) {
            UpdateLog.dTag("DefaultUpdateService", "[taskStart] $task")
            callback.onStart()
        }

        override fun taskEnd(task: DownloadTask, cause: EndCause, realCause: Exception?, model: Listener1Assist.Listener1Model) {
            UpdateLog.dTag("DefaultUpdateService", "[taskEnd] $task, $cause")
            if (cause == EndCause.COMPLETED) {
                callback.onSuccess(task.file)
            } else if (cause == EndCause.ERROR) {
                callback.onError(realCause)
            }
        }

        override fun progress(task: DownloadTask, currentOffset: Long, totalLength: Long) {
            UpdateLog.dTag("DefaultUpdateService", "[progress] $currentOffset, $totalLength")
            val process = currentOffset.toFloat() / totalLength
            callback.onProgress(process, totalLength)
        }

        override fun connected(task: DownloadTask, blockCount: Int, currentOffset: Long, totalLength: Long) {
            UpdateLog.dTag("DefaultUpdateService", "[connected] $blockCount, $currentOffset, $totalLength")
        }

        override fun retry(task: DownloadTask, cause: ResumeFailedCause) {
            UpdateLog.dTag("DefaultUpdateService", "[retry] $task, $cause")
        }

    }
}